package com.zz.springboot.processor.bag.strategy;

import com.zz.springboot.anno.StrategyKeywords;
import com.zz.springboot.anno.StrategyType;
import com.zz.springboot.constant.TypeConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类型索引管理器
 */
@Component
@Slf4j
public class   TypeIndexManager {

    private Map<String, String> keywordToTypeMap = new HashMap<>();

    @Autowired
    private List<BagStrategy> strategies;

    /**
     * 初始化<分类明细,缩写type>的映射关系
     */
    @PostConstruct
    public void initTypeIndex() {
        // 构建关键字到类型的映射
/* //这种方式不便于扩展，借助注解提高可扩展性
        addToIndex(TypeConstants.animalConstant, "animal");
        addToIndex(TypeConstants.bigLittleConstant, "bigLittle");
        addToIndex(TypeConstants.oddEvenConstant, "oddEven");
        addToIndex(TypeConstants.bigLittleOddsEvensConstant, "blOe");
        addToIndex(TypeConstants.colorConstant, "color");
        addToIndex(TypeConstants.colorOddsEvensConstant, "colorOe");
        addToIndex(TypeConstants.digitConstant, "tail");
        addToIndex(TypeConstants.headConstant, "head");
        addToIndex(TypeConstants.fiveElementsConstant, "fiveElements");
        addToIndex(TypeConstants.poultryWildConstant, "poultryWild");
 */
        keywordToTypeMap.clear();
        for (BagStrategy strategy : strategies) {
            StrategyType typeAnnotation = strategy.getClass().getAnnotation(StrategyType.class);
            StrategyKeywords keywordsAnnotation = strategy.getClass().getAnnotation(StrategyKeywords.class);

            if (typeAnnotation != null && keywordsAnnotation != null) {
                String type = typeAnnotation.value();
                String[] keywords = keywordsAnnotation.value();
                addToIndex(Arrays.asList(keywords), type);
            }
        }
    }

    private void addToIndex(List<String> keywords, String type) {
        for (String keyword : keywords) {
            keywordToTypeMap.put(keyword, type);
        }
    }

    /**
     * 根据文本查找匹配的类型映射<分类明细,缩写type>
     *
     * @param text 输入文本
     * @return 匹配的关键字和类型。如：<"绿双","colorOddsEvens">、<"大","bigLittle">
     */
    public Map.Entry<String, String> findTypeByKeywords(String text) {
        // 1.分类明细排序
        List<String> sortedKeywords = new ArrayList<>(keywordToTypeMap.keySet());
        sortedKeywords.sort((a, b) -> {
            // 首先按长度降序排序。优先匹配长关键字（避免"单"匹配覆盖"红单"）
            int lengthCompare = b.length() - a.length();
            if (lengthCompare != 0) {
                return lengthCompare;
            }
            // 长度相同时按字母顺序排序（保证结果稳定）
            return a.compareTo(b);
        });
        // 2.匹配关键字，并返回【正确的】<分类明细,缩写type> （比如“红单”就不能找“单”对应的类型）
        for (String keyword : sortedKeywords) {
            if (text.contains(keyword)) {
                //注意：这里匹配到第一个关键字就会返回
                return new AbstractMap.SimpleEntry<>(keyword, keywordToTypeMap.get(keyword));
            }
        }

        return null;
    }

    /**
     * 获取所有匹配的关键字映射（适用于包含多个关键字的情况）
     *
     * @param text 输入文本
     * @return 匹配的关键字和类型列表
     */
    public List<Map.Entry<String, String>> findAllTypesByKeywords(String text) {
        List<Map.Entry<String, String>> results = new ArrayList<>();

        // 按关键字长度降序排序
        List<String> sortedKeywords = new ArrayList<>(keywordToTypeMap.keySet());
        sortedKeywords.sort((a, b) -> b.length() - a.length());

        for (String keyword : sortedKeywords) {
            if (text.contains(keyword)) {
                results.add(new AbstractMap.SimpleEntry<>(keyword, keywordToTypeMap.get(keyword)));
            }
        }

        return results;
    }

    /**
     * 获取关键字
     * 但该方法不适合识别多个关键字的情况，如“包鸡狗各10元”，此时只会识别第一个关键字
     * @param text 输入文本
     * @return 关键字
     */
    public String getKeyWord(String text) {
        Map.Entry<String, String> entry = findTypeByKeywords(text);
        if (entry == null) {
            log.error("无法识别的输入格式:{} ", text);
            throw new IllegalArgumentException("无法识别的输入格式: " + text);
        }
        return entry.getKey();
    }

    /**
     * 获取所有关键字
     * @param text 输入文本
     * @return 所有关键字
     */
    public String getAllKeyWords(String text){
        return findAllTypesByKeywords(text).stream()
                .map(Map.Entry::getKey)
                .collect(Collectors.joining(","));
    }

    /**
     * 获取关键字对应的类型
     *
     * @param keyword 关键字
     * @return 类型名称
     */
    public String getTypeByKeyword(String keyword) {
        return keywordToTypeMap.get(keyword);
    }

    /**
     * 获取指定类型的所有关键字
     *
     * @param type 类型名称
     * @return 该类型的所有关键字
     */
    public List<String> getKeywordsByType(String type) {
        return keywordToTypeMap.entrySet().stream()
                .filter(entry -> type.equals(entry.getValue()))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    /**
     * 获取所有类型
     *
     * @return 所有类型的集合
     */
    public Set<String> getAllTypes() {
        return new HashSet<>(keywordToTypeMap.values());
    }
}
